package com.hk.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hk.constant.CacheConstants;
import com.hk.constant.HttpStatus;
import com.hk.constant.UserConstants;
import com.hk.domain.LoginInfo;
import com.hk.domain.User;
import com.hk.dto.LoginDto;
import com.hk.mapper.UserMapper;
import com.hk.service.LoginService;
import com.hk.utils.ArithmeticVerifyCodeUtils;
import com.hk.utils.JwtUtils;
import com.hk.vo.LoginVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.TimeUnit;


@Service
@Slf4j
public class LoginServiceImpl extends ServiceImpl<UserMapper, User> implements LoginService {
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public LoginInfo captchaImage(){
        // 生成算术表达式和结果
        ArithmeticVerifyCodeUtils.ArithmeticInfo info = ArithmeticVerifyCodeUtils.generateArithmetic();
        String expression = info.getExpression();
        int result = info.getResult();
        //生成uuid并保存到redis中
        String uuid = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set(uuid+ CacheConstants.CAPTCHA_CODE_KEY, result, UserConstants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
        BufferedImage image = ArithmeticVerifyCodeUtils.createImage(expression);
        ByteArrayOutputStream os=null;
        // 转换为字节数组并返回
        try {
             os = new ByteArrayOutputStream();
            ImageIO.write(image, "JPEG", os);
        } catch (IOException e) {
            log.info("字节数组转化异常");
        }
        byte[] imageBytes = os.toByteArray();
        String imgs = Base64.getEncoder().encodeToString(imageBytes);

        LoginInfo loginInfo = new LoginInfo().builder().img(imgs)
                .msg(CacheConstants.LOGIN_SUCCESS1)
                .code(HttpStatus.SUCCESS)
                .uuid(uuid).build();

        return loginInfo;
    }

    @Override
    public LoginVo login(LoginDto loginDto) throws Exception {
        String uuid = loginDto.getUuid();
        LoginVo loginVo=null;
        if(redisTemplate.hasKey(uuid+ CacheConstants.CAPTCHA_CODE_KEY)){
            Integer code = (Integer) redisTemplate.opsForValue().get(uuid+ CacheConstants.CAPTCHA_CODE_KEY);
            if(!code.equals(loginDto.getCode())){
                throw new Exception("验证码错误");
            }
            //验证码验证成功
            redisTemplate.delete(uuid+ CacheConstants.CAPTCHA_CODE_KEY);
            LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(User::getUserName,loginDto.getUsername());
            wrapper.eq(User::getPassword,loginDto.getPassword());
            User user = super.getOne(wrapper);
            if(user==null){
                throw new Exception("用户名或密码错误");
            }
            //登录成功，生成token
            HashMap<String, Object> claims = new HashMap<>();
            claims.put("userId",user.getUserId());
            claims.put("userName",user.getUserName());
            claims.put("password",user.getPassword());
            String token = JwtUtils.generateJwt(claims);
             loginVo = new LoginVo().builder().token(token)
                    .msg(CacheConstants.LOGIN_SUCCESS2)
                    .code(HttpStatus.SUCCESS).build();
        }
        return loginVo;
    }
}
